package com.lzw;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Description;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 队列LOG
 *
 * @author liuzw
 * @date 2021/7/15
 */
@Aspect
@Component
@Slf4j
public class RabbitMqLogAspect {

    @Autowired
    private Environment environment;

    public RabbitMqLogAspect(Environment environment) {
        this.environment = environment;
    }

    @Before(value = "execution(public  void  org.springframework.amqp.rabbit.core.RabbitTemplate.convertAndSend(..))")
    public void sendMsg(JoinPoint joinPoint) throws Throwable {
        log.info("send to queue [{}:{}:{}:{}] ", joinPoint.getArgs());
    }

    @Before(value = "@annotation(org.springframework.amqp.rabbit.annotation.RabbitListener)")
    public void receiverMsg(JoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Class<?> clazz = signature.getDeclaringType();
        Description desc = clazz.getAnnotation(Description.class);
        Method method = signature.getMethod();
        RabbitListener lister = method.getAnnotation(RabbitListener.class);
        Set<String> queueName = new HashSet<>();
        if (lister != null) {
            Set<String> queueNameValue = Arrays.stream(lister.queues()).collect(Collectors.toSet());
            queueNameValue.addAll(Arrays.stream(lister.queuesToDeclare()).map(Queue::value).collect(Collectors.toSet()));
            if (!CollectionUtils.isEmpty(queueNameValue)) {
                queueName = queueNameValue.stream().map(value -> {
                    if (StringUtils.isNotBlank(value)) {
                        return environment.resolvePlaceholders(value);
                    }
                    return null;
                }).collect(Collectors.toSet());
            }
        }
        log.info("receiver queue [{}] name [{}] data [{}]", desc == null ? null : desc.value(), StringUtils.join(queueName, ","), joinPoint.getArgs());
    }

}
